/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Codigo;

import java.awt.Desktop;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.net.URI;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.regex.PatternSyntaxException;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.RowFilter;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

/**
 *
 * @author kyerte
 */
public class FrmBirthdays extends javax.swing.JFrame {

    ModeloTabla modeloTabla;
    java.util.Date fechaSeleccionada;
    Calendar fechaOperaciones;
    int dia;
    int mes;
    ArrayList<String> correos;
    String sistemaOperativo = null;
    TableRowSorter<TableModel> sorter;

    /**
     * Creates new form FrmBirthDays
     */
    public FrmBirthdays() {
        this.setIconImage(new ImageIcon(getClass().getResource("/Imagenes/Balloons35.png")).getImage());
        initComponents();
        obtenerFechaSeleccionada();
        modeloTabla = new ModeloTabla(mes, dia);
        tablaResultados.setModel(modeloTabla);
        acomodarColumnas();
        sistemaOperativo = System.getProperty("os.name");

        sorter = new TableRowSorter<TableModel>(modeloTabla);
        tablaResultados.setRowSorter(sorter);

        txtFiltro.addKeyListener(new KeyListener() {
            @Override
            public void keyTyped(KeyEvent e) {
                String texto = txtFiltro.getText();
                if (texto.length() == 0) {
                    sorter.setRowFilter(null);

                } else {
                    try {
                        sorter.setRowFilter(RowFilter.regexFilter(texto));
                    } catch (PatternSyntaxException ex) {
                        JOptionPane.showMessageDialog(null, "Patrón de exp reg incorrecto",
                                "Cumpleaños", JOptionPane.ERROR_MESSAGE);
                    }
                }
            }

            @Override
            public void keyPressed(KeyEvent arg0) {
            }

            @Override
            public void keyReleased(KeyEvent arg0) {
            }
        });
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        calendario = new com.toedter.calendar.JCalendar();
        cmdFiltrar = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        tablaResultados = new javax.swing.JTable();
        jSeparator1 = new javax.swing.JSeparator();
        cmdFiltarMes = new javax.swing.JButton();
        cmdEnviarCorreo = new javax.swing.JButton();
        panelFiltro = new javax.swing.JPanel();
        txtFiltro = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Cumpleaños");

        cmdFiltrar.setMnemonic('f');
        cmdFiltrar.setText("Filtrar por fecha");
        cmdFiltrar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdFiltrarActionPerformed(evt);
            }
        });

        tablaResultados.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null, null},
                {null, null, null, null, null},
                {null, null, null, null, null},
                {null, null, null, null, null}
            },
            new String [] {
                "idCliente", "Nombre", "Correo", "Fecha de nacimiento", "Edad"
            }
        ) {
            boolean[] canEdit = new boolean [] {
                false, false, false, false, false
            };

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        jScrollPane1.setViewportView(tablaResultados);

        jSeparator1.setOrientation(javax.swing.SwingConstants.VERTICAL);

        cmdFiltarMes.setMnemonic('m');
        cmdFiltarMes.setText("Filtrar por mes");
        cmdFiltarMes.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdFiltarMesActionPerformed(evt);
            }
        });

        cmdEnviarCorreo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Imagenes/E-mail-32.png"))); // NOI18N
        cmdEnviarCorreo.setMnemonic('e');
        cmdEnviarCorreo.setText("Enviar correo");
        cmdEnviarCorreo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdEnviarCorreoActionPerformed(evt);
            }
        });

        panelFiltro.setBorder(javax.swing.BorderFactory.createTitledBorder("Filtro"));

        txtFiltro.setFont(new java.awt.Font("Ubuntu", 2, 18)); // NOI18N
        txtFiltro.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtFiltroActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout panelFiltroLayout = new javax.swing.GroupLayout(panelFiltro);
        panelFiltro.setLayout(panelFiltroLayout);
        panelFiltroLayout.setHorizontalGroup(
            panelFiltroLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelFiltroLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(txtFiltro)
                .addContainerGap())
        );
        panelFiltroLayout.setVerticalGroup(
            panelFiltroLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelFiltroLayout.createSequentialGroup()
                .addContainerGap(25, Short.MAX_VALUE)
                .addComponent(txtFiltro, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(24, 24, 24))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(panelFiltro, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 789, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(32, 32, 32)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(calendario, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                        .addComponent(cmdEnviarCorreo, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(cmdFiltarMes, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(cmdFiltrar, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 178, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(calendario, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(cmdFiltrar, javax.swing.GroupLayout.PREFERRED_SIZE, 41, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(cmdFiltarMes, javax.swing.GroupLayout.PREFERRED_SIZE, 41, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 26, Short.MAX_VALUE))
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(panelFiltro, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(cmdEnviarCorreo, javax.swing.GroupLayout.PREFERRED_SIZE, 58, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(28, 28, 28))))
            .addComponent(jSeparator1, javax.swing.GroupLayout.Alignment.TRAILING)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void cmdFiltrarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdFiltrarActionPerformed
        obtenerFechaSeleccionada();

        try {

            modeloTabla.realizarConsulta(mes, dia);

            acomodarColumnas();

        } catch (SQLException ex) {
            ex.printStackTrace();
        } catch (IllegalStateException ex) {
            ex.printStackTrace();
        }

    }//GEN-LAST:event_cmdFiltrarActionPerformed

    private void cmdFiltarMesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdFiltarMesActionPerformed
        obtenerFechaSeleccionada();
        try {
            modeloTabla.realizarConsultaMes(mes);
            acomodarColumnas();
        } catch (SQLException ex) {
            ex.printStackTrace();
        } catch (IllegalStateException ex) {
            ex.printStackTrace();
        }
    }//GEN-LAST:event_cmdFiltarMesActionPerformed

    private void cmdEnviarCorreoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdEnviarCorreoActionPerformed
        txtFiltro.setText("");
        sorter.setRowFilter(null);
        
        correos = obtenerCorreosSeleccionados();

        if (correos.size() > 0) {
            enviarCorreoElectronico();
        } else {

            JOptionPane.showMessageDialog(null, "No se seleccionó ninguna dirección"
                    + "", "Enviar correo", JOptionPane.INFORMATION_MESSAGE);

        }

    }//GEN-LAST:event_cmdEnviarCorreoActionPerformed

    private void txtFiltroActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtFiltroActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_txtFiltroActionPerformed

    private void acomodarColumnas() {
        tablaResultados.getColumnModel().getColumn(0).setPreferredWidth(1);
        tablaResultados.getColumnModel().getColumn(1).setPreferredWidth(200);
        tablaResultados.getColumnModel().getColumn(2).setPreferredWidth(100);
        tablaResultados.getColumnModel().getColumn(3).setPreferredWidth(30);
        tablaResultados.getColumnModel().getColumn(4).setPreferredWidth(5);

    }

    private void obtenerFechaSeleccionada() {
        fechaSeleccionada = new java.util.Date(calendario.getDate().getTime());
        fechaOperaciones = Calendar.getInstance();
        fechaOperaciones.setTime(fechaSeleccionada);
        dia = fechaOperaciones.get(Calendar.DAY_OF_MONTH);
        mes = fechaOperaciones.get(Calendar.MONTH) + 1;
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private com.toedter.calendar.JCalendar calendario;
    private javax.swing.JButton cmdEnviarCorreo;
    private javax.swing.JButton cmdFiltarMes;
    private javax.swing.JButton cmdFiltrar;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JPanel panelFiltro;
    private javax.swing.JTable tablaResultados;
    private javax.swing.JTextField txtFiltro;
    // End of variables declaration//GEN-END:variables

    private ArrayList<String> obtenerCorreosSeleccionados() {

        int[] filasSeleccionadas = tablaResultados.getSelectedRows();
        ArrayList<String> correosObtenidos = new ArrayList<String>();

        if (filasSeleccionadas.length > 0) {
            for (int x = 0; x < filasSeleccionadas.length; x++) {
                if (!modeloTabla.getValueAt(filasSeleccionadas[x], 2).toString().equals("")) {
                    correosObtenidos.add(modeloTabla.getValueAt(filasSeleccionadas[x], 2).toString());
                }
            }
        }
        return correosObtenidos;
    }

    private void enviarCorreoElectronico() {
        String direcciones = "";

        for (int x = 0; x < correos.size(); x++) {
            direcciones += correos.get(x) + ",";
        }

        Desktop desktop = null;

        if (Desktop.isDesktopSupported()) {

            desktop = Desktop.getDesktop();

            try {

                String comando = "mailto:" + direcciones + "?subject=¡Feliz%20Cumpleaños!";
                URI uri = URI.create(comando);
                desktop.mail(uri);

            } catch (IOException ex) {
                ex.printStackTrace();
                JOptionPane.showMessageDialog(null, "Ocurrió un problema al enviar "
                        + "el correo electrónico", "Enviar correo", JOptionPane.ERROR_MESSAGE);
            } catch (IllegalArgumentException ex2) {
                JOptionPane.showMessageDialog(null, "Dirección de correo no válida",
                        "Enviar correo", JOptionPane.WARNING_MESSAGE);
            }
        }

    }
}

class ModeloTabla extends AbstractTableModel {

    private final String[] NOMBRE_COLUMNAS = {"idCliente", "Nombre", "Correo",
        "Fecha de nacimiento", "Edad"};
    private PreparedStatement obtenerCumpleaniosFecha;
    private PreparedStatement obtenerCumpleaniosMes;
    private Connection conexion;
    private ResultSet conjuntoResultados;
    private ResultSetMetaData metaDatos;
    private int numeroDeFilas;
    private boolean conectadoABaseDatos = false;

    ModeloTabla(int mes, int dia) {

        conexion = FrmPrincipal.conexion;
        conectadoABaseDatos = true;

        try {

            obtenerCumpleaniosFecha = conexion.prepareStatement("SELECT idCliente, Nombre, "
                    + "EMail, FechaNacimiento, (YEAR(CURDATE())-YEAR(FechaNacimiento)) "
                    + "- (RIGHT(CURDATE(),5)<RIGHT(FechaNacimiento,5)) AS Edad "
                    + "FROM Clientes WHERE MONTH(FechaNacimiento)=? AND "
                    + "DAYOFMONTH(FechaNacimiento)=?");

            obtenerCumpleaniosMes = conexion.prepareStatement("SELECT idCliente, Nombre, "
                    + "EMail, FechaNacimiento, (YEAR(CURDATE())-YEAR(FechaNacimiento)) "
                    + "- (RIGHT(CURDATE(),5)<RIGHT(FechaNacimiento,5)) AS Edad "
                    + "FROM Clientes WHERE MONTH(FechaNacimiento)=? ORDER BY FechaNacimiento");

            realizarConsultaMes(mes);

        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }

    public void realizarConsulta(int mes, int dia) throws SQLException, IllegalStateException {

        if (!conectadoABaseDatos) {
            throw new IllegalStateException("No hay conexión a la base de datos");
        }

        obtenerCumpleaniosFecha.setInt(1, mes);
        obtenerCumpleaniosFecha.setInt(2, dia);
        conjuntoResultados = obtenerCumpleaniosFecha.executeQuery();

        metaDatos = conjuntoResultados.getMetaData();

        conjuntoResultados.last();
        numeroDeFilas = conjuntoResultados.getRow();

        fireTableStructureChanged();
    }

    public void realizarConsultaMes(int mes) throws SQLException, IllegalStateException {

        if (!conectadoABaseDatos) {
            throw new IllegalStateException("No hay conexión a la base de datos");
        }

        obtenerCumpleaniosMes.setInt(1, mes);
        conjuntoResultados = obtenerCumpleaniosMes.executeQuery();

        metaDatos = conjuntoResultados.getMetaData();

        conjuntoResultados.last();
        numeroDeFilas = conjuntoResultados.getRow();

        fireTableStructureChanged();
    }

    @Override
    public Class getColumnClass(int columna) throws IllegalStateException {

        if (!conectadoABaseDatos) {
            throw new IllegalStateException("No hay conexión a la base de datos");
        }

        try {
            String nombreClase = metaDatos.getColumnClassName(columna + 1);

            return Class.forName(nombreClase);
        } catch (Exception excepcion) {
            excepcion.printStackTrace();
        }

        return Object.class;
    }

    @Override
    public int getColumnCount() throws IllegalStateException {

        if (!conectadoABaseDatos) {
            throw new IllegalStateException("No hay conexión a la base de datos");
        }

        try {
            return metaDatos.getColumnCount();
        } catch (SQLException excepcionSql) {
            excepcionSql.printStackTrace();
        }
        return 0;
    }

    @Override
    public String getColumnName(int columna) throws IllegalStateException {

        if (!conectadoABaseDatos) {
            throw new IllegalStateException("No hay conexión a la base de datos");
        }

        try {
            return NOMBRE_COLUMNAS[columna];

        } catch (Exception excepcion) {
            excepcion.printStackTrace();
        }

        return "";
    }

    @Override
    public int getRowCount() throws IllegalStateException {

        if (!conectadoABaseDatos) {
            throw new IllegalStateException("No hay conexión a la base de datos");
        }

        return numeroDeFilas;
    }

    @Override
    public Object getValueAt(int fila, int columna) throws IllegalStateException {

        if (!conectadoABaseDatos) {
            throw new IllegalStateException("No hay conexión a la base de datos");
        }

        try {
            conjuntoResultados.absolute(fila + 1);
            return conjuntoResultados.getObject(columna + 1);
        } catch (SQLException excepcionSql) {
            excepcionSql.printStackTrace();
        }

        return "";
    }

    public void desconectarDeBaseDeDatos() {
        if (conectadoABaseDatos) {

            try {
                conjuntoResultados.close();
                conexion.close();
            } catch (SQLException ex) {
                ex.printStackTrace();
            } finally {
                conectadoABaseDatos = false;
            }
        }
    }
}
